Restructure code
authorAleksey Kladov <aleksey.kladov@gmail.com>
Sat, 8 Jul 2017 16:45:07 +0000 (19:45 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Sat, 8 Jul 2017 16:45:07 +0000 (19:45 +0300)
src/cargo/util/toml/mod.rs
src/cargo/util/toml/targets.rs

index e2c7d08f96eff28e33fce5aab5efb8cc026f62fe..15fa98bbe7e278465fe8272bab1c42c74a37ab54 100644 (file)
@@ -42,7 +42,8 @@ fn do_read_manifest(contents: &str,
     let project_root = manifest_file.parent().unwrap();
 
     let toml = {
-        let pretty_filename = util::without_prefix(manifest_file, config.cwd()).unwrap_or(manifest_file);
+        let pretty_filename =
+            util::without_prefix(manifest_file, config.cwd()).unwrap_or(manifest_file);
         parse(contents, pretty_filename, config)?
     };
 
@@ -516,7 +517,7 @@ impl TomlManifest {
         // If we have no lib at all, use the inferred lib if available
         // If we have a lib with a path, we're done
         // If we have a lib with no path, use the inferred lib or_else package name
-        let targets = targets(me, project_root, project_name, &project.build)?;
+        let targets = targets(me, project_name, project_root, &project.build)?;
 
         if targets.is_empty() {
             debug!("manifest has no build targets");
@@ -964,94 +965,13 @@ impl TomlTarget {
         }
     }
 
-    fn validate_library_name(&self) -> CargoResult<()> {
-        match self.name {
-            Some(ref name) => {
-                if name.trim().is_empty() {
-                    Err("library target names cannot be empty.".into())
-                } else if name.contains('-') {
-                    Err(format!("library target names cannot contain hyphens: {}",
-                                 name).into())
-                } else {
-                    Ok(())
-                }
-            },
-            None => Ok(())
-        }
-    }
-
-    fn validate_binary_name(&self) -> CargoResult<()> {
-        match self.name {
-            Some(ref name) => {
-                if name.trim().is_empty() {
-                    Err("binary target names cannot be empty.".into())
-                } else {
-                    Ok(())
-                }
-            },
-            None => Err("binary target bin.name is required".into())
-        }
-    }
-
-    fn validate_example_name(&self) -> CargoResult<()> {
-        match self.name {
-            Some(ref name) => {
-                if name.trim().is_empty() {
-                    Err("example target names cannot be empty".into())
-                } else {
-                    Ok(())
-                }
-            },
-            None => Err("example target example.name is required".into())
-        }
-    }
-
-    fn validate_test_name(&self) -> CargoResult<()> {
-        match self.name {
-            Some(ref name) => {
-                if name.trim().is_empty() {
-                    Err("test target names cannot be empty".into())
-                } else {
-                    Ok(())
-                }
-            },
-            None => Err("test target test.name is required".into())
-        }
-    }
-
-    fn validate_bench_name(&self) -> CargoResult<()> {
-        match self.name {
-            Some(ref name) => {
-                if name.trim().is_empty() {
-                    Err("bench target names cannot be empty".into())
-                } else {
-                    Ok(())
-                }
-            },
-            None => Err("bench target bench.name is required".into())
-        }
-    }
-
-    fn validate_crate_type(&self) -> CargoResult<()> {
-        // Per the Macros 1.1 RFC:
-        //
-        // > Initially if a crate is compiled with the proc-macro crate type
-        // > (and possibly others) it will forbid exporting any items in the
-        // > crate other than those functions tagged #[proc_macro_derive] and
-        // > those functions must also be placed at the crate root.
-        //
-        // A plugin requires exporting plugin_registrar so a crate cannot be
-        // both at once.
-        if self.plugin == Some(true) && self.proc_macro() == Some(true) {
-            Err("lib.plugin and lib.proc-macro cannot both be true".into())
-        } else {
-            Ok(())
-        }
-    }
-
     fn proc_macro(&self) -> Option<bool> {
         self.proc_macro.or(self.proc_macro2)
     }
+
+    fn crate_types(&self) -> Option<&Vec<String>> {
+        self.crate_type.as_ref().or(self.crate_type2.as_ref())
+    }
 }
 
 impl fmt::Debug for PathValue {
index 588b2d6761788a6711a05b8abee3e8e4572659a2..d5ec3a96d82ffb3faca9366da42a0b48a92524a4 100644 (file)
@@ -20,98 +20,14 @@ use super::{TomlTarget, LibKind, PathValue, TomlManifest, StringOrBool,
             TomlLibTarget, TomlBinTarget, TomlBenchTarget, TomlExampleTarget, TomlTestTarget};
 
 
-/// Implicit Cargo targets, defined by conventions.
-struct Layout {
-    root: PathBuf,
-    lib: Option<PathBuf>,
-    bins: Vec<PathBuf>,
-    examples: Vec<PathBuf>,
-    tests: Vec<PathBuf>,
-    benches: Vec<PathBuf>,
-}
-
-impl Layout {
-    /// Returns a new `Layout` for a given root path.
-    /// The `root_path` represents the directory that contains the `Cargo.toml` file.
-    pub fn from_project_path(root_path: &Path) -> Layout {
-        let mut lib = None;
-        let mut bins = vec![];
-        let mut examples = vec![];
-        let mut tests = vec![];
-        let mut benches = vec![];
-
-        let lib_candidate = root_path.join("src").join("lib.rs");
-        if fs::metadata(&lib_candidate).is_ok() {
-            lib = Some(lib_candidate);
-        }
-
-        try_add_file(&mut bins, root_path.join("src").join("main.rs"));
-        try_add_files(&mut bins, root_path.join("src").join("bin"));
-        try_add_mains_from_dirs(&mut bins, root_path.join("src").join("bin"));
-
-        try_add_files(&mut examples, root_path.join("examples"));
-
-        try_add_files(&mut tests, root_path.join("tests"));
-        try_add_files(&mut benches, root_path.join("benches"));
-
-        Layout {
-            root: root_path.to_path_buf(),
-            lib: lib,
-            bins: bins,
-            examples: examples,
-            tests: tests,
-            benches: benches,
-        }
-    }
-}
-
-fn try_add_file(files: &mut Vec<PathBuf>, file: PathBuf) {
-    if fs::metadata(&file).is_ok() {
-        files.push(file);
-    }
-}
-
-// Add directories form src/bin which contain main.rs file
-fn try_add_mains_from_dirs(files: &mut Vec<PathBuf>, root: PathBuf) {
-    if let Ok(new) = fs::read_dir(&root) {
-        let new: Vec<PathBuf> = new.filter_map(|i| i.ok())
-            // Filter only directories
-            .filter(|i| {
-                i.file_type().map(|f| f.is_dir()).unwrap_or(false)
-                // Convert DirEntry into PathBuf and append "main.rs"
-            }).map(|i| {
-            i.path().join("main.rs")
-            // Filter only directories where main.rs is present
-        }).filter(|f| {
-            f.as_path().exists()
-        }).collect();
-        files.extend(new);
-    }
-}
-
-fn try_add_files(files: &mut Vec<PathBuf>, root: PathBuf) {
-    if let Ok(new) = fs::read_dir(&root) {
-        files.extend(new.filter_map(|dir| {
-            dir.map(|d| d.path()).ok()
-        }).filter(|f| {
-            f.extension().and_then(|s| s.to_str()) == Some("rs")
-        }).filter(|f| {
-            // Some unix editors may create "dotfiles" next to original
-            // source files while they're being edited, but these files are
-            // rarely actually valid Rust source files and sometimes aren't
-            // even valid UTF-8. Here we just ignore all of them and require
-            // that they are explicitly specified in Cargo.toml if desired.
-            f.file_name().and_then(|s| s.to_str()).map(|s| {
-                !s.starts_with('.')
-            }).unwrap_or(true)
-        }))
-    }
-    /* else just don't add anything if the directory doesn't exist, etc. */
-}
-
-pub fn targets(me: &TomlManifest, project_root: &Path, project_name: &str, custom_build: &Option<StringOrBool>) -> CargoResult<Vec<Target>> {
+pub fn targets(manifest: &TomlManifest,
+               project_name: &str,
+               project_root: &Path,
+               custom_build: &Option<StringOrBool>)
+               -> CargoResult<Vec<Target>> {
     let layout = Layout::from_project_path(project_root);
-    let lib = match me.lib {
+
+    let lib = match manifest.lib {
         Some(ref lib) => {
             lib.validate_library_name()?;
             lib.validate_crate_type()?;
@@ -128,7 +44,7 @@ pub fn targets(me: &TomlManifest, project_root: &Path, project_name: &str, custo
         None => inferred_lib_target(project_name, &layout),
     };
 
-    let bins = match me.bin {
+    let bins = match manifest.bin {
         Some(ref bins) => {
             for target in bins {
                 target.validate_binary_name()?;
@@ -145,7 +61,7 @@ pub fn targets(me: &TomlManifest, project_root: &Path, project_name: &str, custo
         }
     }
 
-    let examples = match me.example {
+    let examples = match manifest.example {
         Some(ref examples) => {
             for target in examples {
                 target.validate_example_name()?;
@@ -155,7 +71,7 @@ pub fn targets(me: &TomlManifest, project_root: &Path, project_name: &str, custo
         None => inferred_example_targets(&layout)
     };
 
-    let tests = match me.test {
+    let tests = match manifest.test {
         Some(ref tests) => {
             for target in tests {
                 target.validate_test_name()?;
@@ -165,7 +81,7 @@ pub fn targets(me: &TomlManifest, project_root: &Path, project_name: &str, custo
         None => inferred_test_targets(&layout)
     };
 
-    let benches = match me.bench {
+    let benches = match manifest.bench {
         Some(ref benches) => {
             for target in benches {
                 target.validate_bench_name()?;
@@ -177,26 +93,26 @@ pub fn targets(me: &TomlManifest, project_root: &Path, project_name: &str, custo
 
     if let Err(e) = unique_names_in_targets(&bins) {
         bail!("found duplicate binary name {}, but all binary targets \
-                   must have a unique name", e);
+               must have a unique name", e);
     }
 
     if let Err(e) = unique_names_in_targets(&examples) {
         bail!("found duplicate example name {}, but all binary targets \
-                   must have a unique name", e);
+               must have a unique name", e);
     }
 
     if let Err(e) = unique_names_in_targets(&benches) {
-        bail!("found duplicate bench name {}, but all binary targets must \
-                   have a unique name", e);
+        bail!("found duplicate bench name {}, but all binary targets \
+               must have a unique name", e);
     }
 
     if let Err(e) = unique_names_in_targets(&tests) {
-        bail!("found duplicate test name {}, but all binary targets must \
-                   have a unique name", e)
+        bail!("found duplicate test name {}, but all binary targets \
+               must have a unique name", e)
     }
 
     // processing the custom build script
-    let new_build = me.maybe_custom_build(custom_build, &layout.root);
+    let new_build = manifest.maybe_custom_build(custom_build, &layout.root);
 
     // Get targets
     let targets = normalize(&layout.root,
@@ -209,6 +125,184 @@ pub fn targets(me: &TomlManifest, project_root: &Path, project_name: &str, custo
     Ok(targets)
 }
 
+
+/// Implicit Cargo targets, defined by conventions.
+struct Layout {
+    root: PathBuf,
+    lib: Option<PathBuf>,
+    bins: Vec<PathBuf>,
+    examples: Vec<PathBuf>,
+    tests: Vec<PathBuf>,
+    benches: Vec<PathBuf>,
+}
+
+impl Layout {
+    /// Returns a new `Layout` for a given root path.
+    /// The `root_path` represents the directory that contains the `Cargo.toml` file.
+    fn from_project_path(root_path: &Path) -> Layout {
+        let mut lib = None;
+        let mut bins = vec![];
+        let mut examples = vec![];
+        let mut tests = vec![];
+        let mut benches = vec![];
+
+        let lib_candidate = root_path.join("src").join("lib.rs");
+        if fs::metadata(&lib_candidate).is_ok() {
+            lib = Some(lib_candidate);
+        }
+
+        try_add_file(&mut bins, root_path.join("src").join("main.rs"));
+        try_add_files(&mut bins, root_path.join("src").join("bin"));
+        try_add_mains_from_dirs(&mut bins, root_path.join("src").join("bin"));
+
+        try_add_files(&mut examples, root_path.join("examples"));
+
+        try_add_files(&mut tests, root_path.join("tests"));
+        try_add_files(&mut benches, root_path.join("benches"));
+
+        return Layout {
+            root: root_path.to_path_buf(),
+            lib: lib,
+            bins: bins,
+            examples: examples,
+            tests: tests,
+            benches: benches,
+        };
+
+        fn try_add_file(files: &mut Vec<PathBuf>, file: PathBuf) {
+            if fs::metadata(&file).is_ok() {
+                files.push(file);
+            }
+        }
+
+        // Add directories form src/bin which contain main.rs file
+        fn try_add_mains_from_dirs(files: &mut Vec<PathBuf>, root: PathBuf) {
+            if let Ok(new) = fs::read_dir(&root) {
+                let new: Vec<PathBuf> = new.filter_map(|i| i.ok())
+                    // Filter only directories
+                    .filter(|i| {
+                        i.file_type().map(|f| f.is_dir()).unwrap_or(false)
+                        // Convert DirEntry into PathBuf and append "main.rs"
+                    }).map(|i| {
+                    i.path().join("main.rs")
+                    // Filter only directories where main.rs is present
+                }).filter(|f| {
+                    f.as_path().exists()
+                }).collect();
+                files.extend(new);
+            }
+        }
+
+        fn try_add_files(files: &mut Vec<PathBuf>, root: PathBuf) {
+            if let Ok(new) = fs::read_dir(&root) {
+                files.extend(new.filter_map(|dir| {
+                    dir.map(|d| d.path()).ok()
+                }).filter(|f| {
+                    f.extension().and_then(|s| s.to_str()) == Some("rs")
+                }).filter(|f| {
+                    // Some unix editors may create "dotfiles" next to original
+                    // source files while they're being edited, but these files are
+                    // rarely actually valid Rust source files and sometimes aren't
+                    // even valid UTF-8. Here we just ignore all of them and require
+                    // that they are explicitly specified in Cargo.toml if desired.
+                    f.file_name().and_then(|s| s.to_str()).map(|s| {
+                        !s.starts_with('.')
+                    }).unwrap_or(true)
+                }))
+            }
+            /* else just don't add anything if the directory doesn't exist, etc. */
+        }
+    }
+}
+
+impl TomlTarget {
+    fn validate_library_name(&self) -> CargoResult<()> {
+        match self.name {
+            Some(ref name) => {
+                if name.trim().is_empty() {
+                    Err("library target names cannot be empty.".into())
+                } else if name.contains('-') {
+                    Err(format!("library target names cannot contain hyphens: {}",
+                                name).into())
+                } else {
+                    Ok(())
+                }
+            },
+            None => Ok(())
+        }
+    }
+
+    fn validate_binary_name(&self) -> CargoResult<()> {
+        match self.name {
+            Some(ref name) => {
+                if name.trim().is_empty() {
+                    Err("binary target names cannot be empty.".into())
+                } else {
+                    Ok(())
+                }
+            },
+            None => Err("binary target bin.name is required".into())
+        }
+    }
+
+    fn validate_example_name(&self) -> CargoResult<()> {
+        match self.name {
+            Some(ref name) => {
+                if name.trim().is_empty() {
+                    Err("example target names cannot be empty".into())
+                } else {
+                    Ok(())
+                }
+            },
+            None => Err("example target example.name is required".into())
+        }
+    }
+
+    fn validate_test_name(&self) -> CargoResult<()> {
+        match self.name {
+            Some(ref name) => {
+                if name.trim().is_empty() {
+                    Err("test target names cannot be empty".into())
+                } else {
+                    Ok(())
+                }
+            },
+            None => Err("test target test.name is required".into())
+        }
+    }
+
+    fn validate_bench_name(&self) -> CargoResult<()> {
+        match self.name {
+            Some(ref name) => {
+                if name.trim().is_empty() {
+                    Err("bench target names cannot be empty".into())
+                } else {
+                    Ok(())
+                }
+            },
+            None => Err("bench target bench.name is required".into())
+        }
+    }
+
+    fn validate_crate_type(&self) -> CargoResult<()> {
+        // Per the Macros 1.1 RFC:
+        //
+        // > Initially if a crate is compiled with the proc-macro crate type
+        // > (and possibly others) it will forbid exporting any items in the
+        // > crate other than those functions tagged #[proc_macro_derive] and
+        // > those functions must also be placed at the crate root.
+        //
+        // A plugin requires exporting plugin_registrar so a crate cannot be
+        // both at once.
+        if self.plugin == Some(true) && self.proc_macro() == Some(true) {
+            Err("lib.plugin and lib.proc-macro cannot both be true".into())
+        } else {
+            Ok(())
+        }
+    }
+}
+
+
 fn normalize(package_root: &Path,
              lib: &Option<TomlLibTarget>,
              bins: &[TomlBinTarget],
@@ -234,11 +328,15 @@ fn normalize(package_root: &Path,
         let path = l.path.clone().unwrap_or_else(
             || PathValue(Path::new("src").join(&format!("{}.rs", l.name())))
         );
-        let crate_types = l.crate_type.as_ref().or(l.crate_type2.as_ref());
-        let crate_types = match crate_types {
+        let crate_types = match l.crate_types() {
             Some(kinds) => kinds.iter().map(|s| LibKind::from_str(s)).collect(),
             None => {
-                vec![if l.plugin == Some(true) { LibKind::Dylib } else if l.proc_macro() == Some(true) { LibKind::ProcMacro } else { LibKind::Lib }]
+                let lib_kind = match (l.plugin, l.proc_macro()) {
+                    (Some(true), _) => LibKind::Dylib,
+                    (_, Some(true)) => LibKind::ProcMacro,
+                    _ => LibKind::Lib
+                };
+                vec![lib_kind]
             }
         };
 
@@ -276,8 +374,7 @@ fn normalize(package_root: &Path,
                 PathValue(default(ex))
             });
 
-            let crate_types = ex.crate_type.as_ref().or(ex.crate_type2.as_ref());
-            let crate_types = match crate_types {
+            let crate_types = match ex.crate_types() {
                 Some(kinds) => kinds.iter().map(|s| LibKind::from_str(s)).collect(),
                 None => Vec::new()
             };